#include "ESP32USBMSC.h"
#include <functional>

// 在文件开头添加静态变量定义
ESP32USBMSC::MountCallback ESP32USBMSC::userMountCallback = nullptr;
ESP32USBMSC::UsbEventCallback ESP32USBMSC::userUsbEventCallback = nullptr;
bool ESP32USBMSC::usbConnected = false;

// 定义静态成员变量
ESP32USBMSC *ESP32USBMSC::instance = nullptr;

// 定义全局单实例
ESP32USBMSC &usbMsc = ESP32USBMSC::getInstance();

// 静态回调函数实现
int32_t ESP32USBMSC::staticOnRead(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
{
    if (instance)
    {
        return instance->onRead(lba, offset, buffer, bufsize);
    }
    return 0;
}

int32_t ESP32USBMSC::staticOnWrite(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
{
    if (instance)
    {
        return instance->onWrite(lba, offset, buffer, bufsize);
    }
    return 0;
}

bool ESP32USBMSC::staticOnStartStop(uint8_t power_condition, bool start, bool load_eject)
{
    if (instance)
    {
        return instance->onStartStop(power_condition, start, load_eject);
    }
    return false;
}

void ESP32USBMSC::staticUsbEventCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    if (instance)
    {
        instance->usbEventCallback(arg, event_base, event_id, event_data);
    }
}

// 构造函数实现
ESP32USBMSC::ESP32USBMSC() : storage(nullptr) {}

// 获取单实例实现
ESP32USBMSC &ESP32USBMSC::getInstance()
{
    if (!instance)
    {
        instance = new ESP32USBMSC();
    }
    return *instance;
}

int32_t ESP32USBMSC::onWrite(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize)
{
    uint32_t secSize = SD_MMC.sectorSize();
    if (!secSize)
        return false;
    int sectors = bufsize / secSize;
    for (int x = 0; x < sectors; x++)
    {
        if (!SD_MMC.writeRAW(buffer + secSize * x, lba + x))
        {
            return false;
        }
    }
    return bufsize;
}

int32_t ESP32USBMSC::onRead(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
{
    uint32_t secSize = SD_MMC.sectorSize();
    if (!secSize)
        return false;
    int sectors = bufsize / secSize;
    for (int x = 0; x < sectors; x++)
    {
        if (!SD_MMC.readRAW((uint8_t *)buffer + (x * secSize), lba + x))
        {
            return false;
        }
    }
    return bufsize;
}

bool ESP32USBMSC::onStartStop(uint8_t power_condition, bool start, bool load_eject)
{
    log_i("Start/Stop power: %u\tstart: %d\teject: %d", power_condition, start, load_eject);
    return true;
}

void ESP32USBMSC::usbEventCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    if (event_base == ARDUINO_USB_EVENTS)
    {
        switch (event_id)
        {
        case ARDUINO_USB_STARTED_EVENT:
            if (!usbConnected)
            {
                usbConnected = true;
                mscMounted = true;
                log_i("USB连接事件");
                // 先触发 USB 事件回调
                if (userUsbEventCallback)
                {
                    userUsbEventCallback(event_id, event_data);
                }
                // 再触发挂载回调
                if (userMountCallback)
                {
                    userMountCallback(true);
                }
            }
            break;
        case ARDUINO_USB_STOPPED_EVENT:
            if (usbConnected)
            {
                usbConnected = false;
                mscMounted = false;
                log_i("USB断开事件");
                // 先触发挂载回调
                if (userMountCallback)
                {
                    userMountCallback(false);
                }
                // 再触发 USB 事件回调
                if (userUsbEventCallback)
                {
                    userUsbEventCallback(event_id, event_data);
                }
            }
            break;
        case ARDUINO_USB_SUSPEND_EVENT:
            log_i("USB挂起事件");
            if (userUsbEventCallback)
            {
                userUsbEventCallback(event_id, event_data);
            }
            break;
        case ARDUINO_USB_RESUME_EVENT:
            log_i("USB恢复事件");
            if (userUsbEventCallback)
            {
                userUsbEventCallback(event_id, event_data);
            }
            break;
        }
    }
}

void ESP32USBMSC::setVendorID(const char *vendorID)
{
    msc.vendorID(vendorID);
}

void ESP32USBMSC::setProductID(const char *productID)
{
    msc.productID(productID);
}

void ESP32USBMSC::setProductRevision(const char *revision)
{
    msc.productRevision(revision);
}

bool ESP32USBMSC::begin(void *storageDevice)
{
    storage = storageDevice;
    msc.onRead(staticOnRead);
    msc.onWrite(staticOnWrite);
    msc.onStartStop(staticOnStartStop);
    msc.mediaPresent(true);
    if (!msc.begin(SD_MMC.numSectors(), SD_MMC.sectorSize()))
    {
        return false;
    }

    // 先注册事件回调
    USB.onEvent(staticUsbEventCallback);

    // 启动 USB
    USB.begin();

    // 检查 USB 是否已经连接
    if (USB)
    {
        usbConnected = true;
        mscMounted = true;
        // 先触发 USB 事件回调
        if (userUsbEventCallback)
        {
            userUsbEventCallback(ARDUINO_USB_STARTED_EVENT, nullptr);
        }
        // 再触发挂载回调
        if (userMountCallback)
        {
            userMountCallback(true);
        }
    }
    else
    {
        // USB 未连接时的状态初始化
        usbConnected = false;
        mscMounted = false;
        // 触发 USB 事件回调
        if (userUsbEventCallback)
        {
            userUsbEventCallback(ARDUINO_USB_STOPPED_EVENT, nullptr);
        }
    }

    return true;
}

void ESP32USBMSC::mountMSC()
{
    msc.mediaPresent(true);
    msc.begin(SD_MMC.numSectors(), SD_MMC.sectorSize());
    USB.begin();
    USB.onEvent(staticUsbEventCallback);
    mscMounted = true;
    if (userMountCallback)
    {
        userMountCallback(true);
    }
}

void ESP32USBMSC::unmountMSC()
{
    msc.end();
    mscMounted = false;
    if (userMountCallback)
    {
        userMountCallback(false);
    }
}

void ESP32USBMSC::registerMountCallback(MountCallback cb)
{
    userMountCallback = cb;
}

void ESP32USBMSC::registerUsbEventCallback(UsbEventCallback cb)
{
    userUsbEventCallback = cb;
}